package com.sgcc.pda.mdrh.utils;

import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.widget.Toast;

import com.qihoo360.replugin.RePlugin;
import com.qihoo360.replugin.model.PluginInfo;
import com.sgcc.pda.baselibrary.ConstPath;
import com.sgcc.pda.baselibrary.utils.DeviceUtil;
import com.sgcc.pda.baselibrary.utils.JsonUtil;
import com.sgcc.pda.baselibrary.utils.LogUtil;
import com.sgcc.pda.baselibrary.utils.ToastUtils;
import com.sgcc.pda.baselibrary.utils.ZipUtil;
import com.sgcc.pda.greendao.entity.AppBaseInfo;
import com.sgcc.pda.mdrh.task.safelibrary.BuildConfig;
import com.sgcc.pda.sdk.utils.FileUtils;
import com.sgcc.pda.sdk.utils.ZoomSPUtils;
import com.sgcc.pda.sdk.utils.db.ContentProviderUtil;
import com.sgcc.pda.sdk.utils.db.SharepreferenceUtil;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.MessageDigest;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

/**
 * App管理类.
 *
 * @author 王沛栋
 * @data 2018/1/8 10:38
 */
public class AppManagerUtil {
    private static final String PKG = "package:";
    private static final String INDEX_HTML = "index.html";
    private static final String APP_NO = "APP_NO";
    private static AppManagerUtil mInstance;

    private final static String APP_PACKAGE_NAME_HARDWARE = "com.sgcc.pda.hw";//硬件协议的包名
    private final static String APP_NAME_HARDWARE = "硬件服务";//硬件协议的包名
    private final static String APP_ASSETS_HARDWARE = "apk/hw.apk";//硬件协议assets资源文件位置

    private final static String APP_PACKAGE_NAME_GIS = "com.sgcc.pda.gis";//硬件协议的包名
    private final static String APP_NAME_GIS = "GIS服务";//硬件协议的包名
    private final static String APP_ASSETS_GIS = "apk/gis.apk";//硬件协议assets资源文件位置

    public final static String FACE_APP_PACKAGE_NAME = "com.sgcc.pda.faceplugin";//人脸识别包名
    public final static int APP_STATES_NO_INSTALL = 0;//应用未安装
    public final static int APP_STATES_DOWNLOADED = 1;//应用下载未安装
    public final static int APP_STATES_INSTALLED = 2;//应用已经安装
    public final static int APP_STATES_NEED_UPDATE = 3;//应用需要强制更新
    public final static int APP_STATES_INSTALLED_DOWNLOADED = 4;//应用已安装已下载新版apk，但未安装
    public final static int APP_STATES_HAVE_NEW_VERSIOIN = 5;//应用有新的版本
    public final static int APP_STATES_HAVE_NOW_VERSIOIN = 6;//应用下载版本的apk没有删除
    public final static int APP_STATE_HAVE_ADD_VERSION = 7;//应用增量更新完毕,需要重启

    public static final String MSG_APP_NO_INSTALL = "应用未安装，请先安装！";
    public static final String MSG_APP_UPLOAD_ERROR = "应用数据上传有误，请检查";
    public static final String MSG_OPEN_NEED_UPDATE_FIRST = "请先在应用市场更新此应用！";
    public static final String MSG_APP_NO_PERMISSION = "对不起,您还没有操作此app的权限!";

    /**
     * 定义所有必须安装的应用集合
     */
    private List<AppBaseInfo> mListNeedInstallApp;

    /**
     * 实现单例模式
     */
    public static AppManagerUtil getInstance() {
        if (mInstance == null) {
            mInstance = new AppManagerUtil();
        }
        return mInstance;
    }

    /**
     * 获取已安装应用列表
     */
    public AppBaseInfo getAppInfoByPackageName(Context context, String packageName) {
        if (TextUtils.isEmpty(packageName)) {
            return null;
        }
        List<PackageInfo> packages = context.getPackageManager().getInstalledPackages(0);
        int dataLength = packages.size();
        AppBaseInfo tmpInfo = null;

        for (int i = 0; i < dataLength; i++) {
            PackageInfo packageInfo = packages.get(i);
            String pName = packageInfo.packageName;
            if (pName.equals(packageName)) {
                tmpInfo = new AppBaseInfo();
                tmpInfo.setAppName(packageInfo.applicationInfo.
                        loadLabel(context.getPackageManager()).toString());
                tmpInfo.setAppPackage(packageInfo.packageName);
                tmpInfo.setVerSortName(packageInfo.versionName);
                tmpInfo.setVerTypeCode(packageInfo.versionCode);

                tmpInfo.setAppIconLocDrawable(packageInfo.applicationInfo.loadIcon(context.getPackageManager()));

                break;
            }
        }
        return tmpInfo;
    }

    /**
     * 获取下载目录的apk文件的信息
     *
     * @param context
     * @return
     */
    public List<AppBaseInfo> getDownloadFileApks(Context context) {
        List<AppBaseInfo> listNew = new ArrayList<>();
        File filePath = new File(ConstPath.DOWNLOAD_PATH);
        File[] files = filePath.listFiles();
        int size = files.length;

        for (int i = 0; i < size; i++) {
            File file = files[i];
            //如果是一个文件
            if (file.isFile()) {
                //获取文件名
                String fileName = file.getName();
                //判断如果是Android文件
                if (fileName.toLowerCase().endsWith(".apk")) {
                    //文件路径
                    String apkPath = file.getAbsolutePath();

                    //创建对象
                    AppBaseInfo info = new AppBaseInfo();
                    //获取路径
                    info.setAppFilePath(apkPath);

                    //获取包管理对象
                    PackageManager pm = context.getPackageManager();
                    PackageInfo packageInfo = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES);
                    if (null == packageInfo) {
                        continue;
                    }
                    String packageName = packageInfo.packageName;

                    LogUtil.e("打印市场的数据包名", packageName);
                    //获取数据库存储的对象
                    AppBaseInfo appBaseInfoDb = ContentProviderUtil.getAppBaseInfoByPackageName(context, packageName);
                    //如果不包含此对象  则不计入记录
                    if (null == appBaseInfoDb) {
                        continue;
                    }

                    //获得包名
                    info.setAppPackage(packageInfo.packageName);
                    //获得版本名称
                    info.setVerTypeName("版本: " + packageInfo.versionName + " 最新版本: " + appBaseInfoDb.getVerTypeName());
                    //获得版本号
                    info.setVerTypeCode(packageInfo.versionCode);

                    info.setAppName(appBaseInfoDb.getAppName());

//                    ApplicationInfo applicationInfo = packageInfo.applicationInfo;
                    //获得图标
//                    info.setAppIconLocDrawable(applicationInfo.loadIcon(pm));
                    info.setAppIcon(appBaseInfoDb.getAppIcon());
                    //临时使用
                    info.setPubType(fileName.substring(0, fileName.lastIndexOf(".")));

                    listNew.add(info);
                }
            }
        }
        return listNew;
    }

    /**
     * 获取已安装应用列表
     */
    public ArrayList<AppBaseInfo> getInstalledAppList(Context context) {
        ArrayList<AppBaseInfo> appList = new ArrayList<>(); //用来存储获取的应用信息数据
        List<PackageInfo> packages = context.getPackageManager().getInstalledPackages(0);
        int dataLength = packages.size();
        if (dataLength > 10) {
            dataLength = 10;
        }

        //com.tl.ha_pssc_app;网格长APP
        for (int i = 0; i < dataLength; i++) {
            PackageInfo packageInfo = packages.get(i);
            AppBaseInfo tmpInfo = new AppBaseInfo();
            tmpInfo.setAppName(packageInfo.applicationInfo.
                    loadLabel(context.getPackageManager()).toString());
            tmpInfo.setAppPackage(packageInfo.packageName);
            tmpInfo.setVerSortName(packageInfo.versionName);
            tmpInfo.setVerTypeCode(packageInfo.versionCode);

            tmpInfo.setAppIconLocDrawable(packageInfo.applicationInfo.
                    loadIcon(context.getPackageManager()));
            //只添加非系统应用  当正式接口什么的完善好以后  请开启下面的代码
            if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                //去除应用本身
                if (!packageInfo.packageName.equals(context.getPackageName())) {
                    appList.add(tmpInfo);//如果非系统应用，则添加至appList
                }
            }
            appList.add(tmpInfo);//如果非系统应用，则添加至appList

        }
        return appList;
    }

    /**
     * 获取系统应用列表
     *
     * @return
     */
    public List<AppBaseInfo> getAppInfoListNeededInstall() {

        if (mListNeedInstallApp == null) {
            mListNeedInstallApp = new ArrayList<>();
            String[] packages = {APP_PACKAGE_NAME_HARDWARE, APP_PACKAGE_NAME_GIS};
            String[] names = {APP_NAME_HARDWARE, APP_NAME_GIS};
            String[] assets = {APP_ASSETS_HARDWARE, APP_ASSETS_GIS};

            int appLength = names.length;
            for (int i = 0; i < appLength; i++) {
                AppBaseInfo info = new AppBaseInfo();
                info.setAppPackage(packages[i]);
                info.setAppName(names[i]);
                info.setAssetsPath(assets[i]);

                mListNeedInstallApp.add(info);
            }
        }
        return mListNeedInstallApp;
    }

    /**
     * 获取已经安装的app应用
     *
     * @return
     */
    public List<AppBaseInfo> getInstalledAppList(Context context, List<AppBaseInfo> list) {
        List<AppBaseInfo> list1 = new ArrayList<>();
        for (AppBaseInfo info : list) {
            if (isAppInstalled(context, info.getAppPackage(), info.getAppInstallMethod())) {
                if (info.getAppPubStatus().equals("1")) {//判断是否被禁用
                    list1.add(info);
                }
            }
        }

        return list1;
    }

    /**
     * 通过包名判断应用是否已经安装
     * installMothed 安装方式
     * 01 原生
     * 02 插件
     * 03 H5
     *
     * @param context       上下文
     * @param packagename   应用包名
     * @param installMothed 安装方式
     * @return 是否安装
     */
    public boolean isAppInstalled(Context context, String packagename, String installMothed) {
        if (TextUtils.isEmpty(packagename)) {
            return false;
        }
        if ("03".equals(installMothed)) {
            //H5
            boolean fileIsExists = FileUtils.fileIsExists(ZipUtil.getStorageAvailable(packagename) + File.separator + INDEX_HTML);
            if (fileIsExists) {
                return true;
            }
            return false;
        } else if ("02".equals(installMothed)) {
            //插件
            return RePlugin.isPluginInstalled(packagename);
        } else {
            try {
                //原生App
                PackageManager packageManager = context.getPackageManager();// 获取packagemanager
                PackageInfo pinfo = packageManager.getPackageInfo(packagename, 0);// 获取所有已安装程序的包信息
                return pinfo != null;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return false;
    }

    /**
     * 通过包名判断应用是否已经安装
     *
     * @param context     上下文
     * @param packagename 应用包名
     * @return 是否安装
     */
    public boolean isAppInstalled(Context context, String packagename) {
        if (TextUtils.isEmpty(packagename)) {
            return false;
        }

        //H5
        boolean h5Installed = FileUtils.fileIsExists(ZipUtil.getStorageAvailable(packagename) + File.separator + "index.html");

        //插件
        boolean pluginInstalled = RePlugin.isPluginInstalled(packagename);

        //原生App
        boolean apkInstalled;
        PackageManager packageManager = context.getPackageManager();// 获取packagemanager
        PackageInfo pinfo = null;// 获取所有已安装程序的包信息
        try {
            pinfo = packageManager.getPackageInfo(packagename, 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        apkInstalled = pinfo != null;

        return apkInstalled || pluginInstalled || h5Installed;
    }

    /**
     * 通过包名判断基础应用是否已经安装
     * 如果已经安装 看是否需要强制升级
     *
     * @param context
     * @param packagename
     * @return
     */
    public boolean appInstalled(Context context, String packagename, HashMap<String, Integer> map, String installMethod) {

        PackageManager packageManager = context.getPackageManager();// 获取packagemanager
        PackageInfo pinfo = null;// 获取所有已安装程序的包信息
        try {
            pinfo = packageManager.getPackageInfo(packagename, 0);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (pinfo != null) {
//            for (int i = 0; i < pinfo.size(); i++) {
//                String pn = pinfo.get(i).packageName;
//                if (packagename.equals(pn)) {
            //如果已经安装 看是否需要强制升级
            int appVersionCode = getAppVersionCode(context, packagename, installMethod);
            int appUpdateCode = map.get(packagename);
            if (appVersionCode < appUpdateCode) {
                //如果已安装基础服务的版本号小于主应用配置的基础服务版本号,则强制安装主应用携带的基础服务
                return false;
            }
            return true;
//                }
//            }
        }
        return false;
    }

    /**
     * 拷贝assets资源文件到sdcard里
     *
     * @param context
     * @param fileName
     * @param path
     * @return
     */
    @SuppressLint("CheckResult")
    public void copyApkFromAssets(final Context context, final String fileName, final String path, final CopyListener listener) {
        Observable.just(0).map(new Function<Integer, Boolean>() {
            @Override
            public Boolean apply(Integer integer) {

                boolean copyIsFinish = false;
                InputStream is = null;
                FileOutputStream fos = null;
                try {
                    is = context.getAssets().open(fileName);
                    File file = new File(path);
                    // 如果存在 则删除 避免安装旧包
                    if (file.exists()) {
                        file.delete();
                    }
                    file.createNewFile();

                    fos = new FileOutputStream(file);
                    byte[] temp = new byte[1024];
                    int i = 0;
                    while ((i = is.read(temp)) > 0) {
                        fos.write(temp, 0, i);
                    }
                    copyIsFinish = true;
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (fos != null) {
                            fos.flush();
                            fos.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        if (is != null) {
                            is.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
                return copyIsFinish;
            }
        }).subscribeOn(Schedulers.io())//指定时间发送在IO线程
                .observeOn(AndroidSchedulers.mainThread())//在主线程处理返回
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean isCopyOk) throws Exception {
                        listener.isCopy(isCopyOk);
                    }
                });

    }

    /**
     * 打开人脸识别登录页面
     */
    public void startFacePlugin(Context context) {
        // 启动插件 人脸识别
        Intent faceIntent = new Intent();
        ComponentName componentName = new ComponentName(FACE_APP_PACKAGE_NAME,"com.sgcc.pda.faceplugin.activity.MarketingFaceLoginGuideActivity");
        faceIntent.setComponent(componentName);
        String userCode = ZoomSPUtils.getUserCode();
        faceIntent.putExtra("userCode", userCode);
        // List<UserInfo.User> person = ZoomSPUtils.getPerson();
        //  faceIntent.putExtra("person", (Serializable) person);
        context.startActivity(faceIntent);
    }

    public interface CopyListener {
        void isCopy(boolean result);
    }

    /**
     * 卸载app
     */
    public void uninstallApp(final Context context, final String packageName) {


        if (TextUtils.isEmpty(packageName)) {
            Toast.makeText(context, "此应用不可卸载", Toast.LENGTH_SHORT).show();
            return;
        }
        try {
            context.getPackageManager().getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            builder.setTitle("卸载应用");
            builder.setMessage("是否卸载该应用？");
            builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Uri uri = Uri.parse(PKG + packageName);
                    Intent intent = new Intent(Intent.ACTION_DELETE, uri);
                    context.startActivity(intent);
                    dialog.dismiss();

                }
            });
            builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    dialogInterface.dismiss();
                }
            });
            builder.create().show();

        } catch (PackageManager.NameNotFoundException e) {
            Toast.makeText(context, "此应用不可卸载", Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 获取当前应用程序的包名
     *
     * @param context 上下文对象
     * @return 返回包名
     */
    public String getAppProcessName(Context context) {
        //当前应用pid
        int pid = android.os.Process.myPid();
        //任务管理类
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        //遍历所有应用
        List<ActivityManager.RunningAppProcessInfo> infos = manager.getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo info : infos) {
            if (info.pid == pid)//得到当前应用
                return info.processName;//返回包名
        }
        return "";
    }

    /**
     * 获取程序 图标
     *
     * @param context
     * @param packname 应用包名
     * @return
     */
    public Drawable getAppIcon(Context context, String packname) {
        try {
            //包管理操作管理类
            PackageManager pm = context.getPackageManager();
            //获取到应用信息
            ApplicationInfo info = pm.getApplicationInfo(packname, 0);
            return info.loadIcon(pm);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取程序的版本名称
     *
     * @param context
     * @param packname
     * @return
     */
    public String getAppVersionName(Context context, String packname) {
        //包管理操作管理类
        PackageManager pm = context.getPackageManager();
        try {
            PackageInfo packinfo = pm.getPackageInfo(packname, 0);
            return packinfo.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();

        }
        return packname;
    }

    /**
     * 获取程序的版本号
     *
     * @param context
     * @param packname
     * @return -1表示没有获取到
     */
    int versionCode;

    public int getAppVersionCode(Context context, String packname, String appType) {

        try {
            if ("02".equals(appType)) {
                //插件apk
                return RePlugin.getPluginVersion(packname);
            } else if ("03".equals(appType)) {
                //html5应用
                String json = JsonUtil.readJsonFile(packname);
                JSONObject jb = null;
                try {
                    jb = new JSONObject(json);
                    String version = jb.getString("versionCode");
                    versionCode = Integer.parseInt(version.replace(".", ""));
                } catch (JSONException e) {
                    e.printStackTrace();
                    return -1;
                }

                return versionCode;
            } else {
                //原生apk
                //包管理操作管理类
                PackageManager pm = context.getPackageManager();
                try {
                    if (packname != null && packname.equals("com.sgcc.pda.safework")) {
                        // 为了实现增量更新的版本控制 版本号和版本名必须这样获取
                        return BuildConfig.VERSION_CODE;
                    } else {
                        String patchversioncode = ContentProviderUtil.getSharepreferenceValue(context, "PATCHVERSIONCODE", packname);
                        if (!TextUtils.isEmpty(patchversioncode)) {
                            return Integer.parseInt(patchversioncode);
                        }
                        PackageInfo packinfo = pm.getPackageInfo(packname, 0);
                        return packinfo.versionCode;
                    }

                } catch (PackageManager.NameNotFoundException e) {
                    e.printStackTrace();
                    return -1;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
    }

    /**
     * 获取程序的版本号
     *
     * @param context
     * @param packname
     * @return -1表示没有获取到
     */
    public int getAppVersionCode(Context context, String packname) {
        if (TextUtils.isEmpty(packname)) {
            return -1;
        }

        int versionCode = -1;

        //插件apk
        versionCode = RePlugin.getPluginVersion(packname);
        if (versionCode == -1) {
            //再看H5
            String json = JsonUtil.readJsonFile(packname);
            try {
                JSONObject jb = new JSONObject(json);
                String version = jb.getString("versionCode");
                versionCode = Integer.parseInt(version.replace(".", ""));
            } catch (JSONException e) {
                e.printStackTrace();
            }

            if (versionCode == -1) {
                //原生apk
                //包管理操作管理类
                PackageManager pm = context.getPackageManager();
                try {
                    if (packname != null && packname.equals("com.sgcc.pda.safework")) {
                        // 为了实现增量更新的版本控制 版本号和版本名必须这样获取
                        versionCode = BuildConfig.VERSION_CODE;
                    } else {
                        String patchversioncode = ContentProviderUtil.getSharepreferenceValue(context, "PATCHVERSIONCODE", packname);
                        if (!TextUtils.isEmpty(patchversioncode)) {
                            versionCode = Integer.parseInt(patchversioncode);
                        }
                        PackageInfo packinfo = pm.getPackageInfo(packname, 0);
                        versionCode = packinfo.versionCode;
                    }

                } catch (PackageManager.NameNotFoundException e) {
                    e.printStackTrace();
                }
            }


        }

        return versionCode;


    }


    /**
     * 获取程序的名字
     *
     * @param context
     * @param packname
     * @return
     */
    public String getAppName(Context context, String packname) {
        //包管理操作管理类
        PackageManager pm = context.getPackageManager();
        try {
            ApplicationInfo info = pm.getApplicationInfo(packname, 0);
            return info.loadLabel(pm).toString();
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();

        }
        return packname;
    }

    /*
     * 获取程序的权限
     */
    public String[] getAllPermissions(Context context, String packname) {
        try {
            //包管理操作管理类
            PackageManager pm = context.getPackageManager();
            PackageInfo packinfo = pm.getPackageInfo(packname, PackageManager.GET_PERMISSIONS);
            //获取到所有的权限
            return packinfo.requestedPermissions;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();

        }
        return null;
    }


    /**
     * 获取程序的签名
     *
     * @param context
     * @param packname
     * @return
     */
    public String getAppSignature(Context context, String packname) {
        try {
            //包管理操作管理类
            PackageManager pm = context.getPackageManager();
            PackageInfo packinfo = pm.getPackageInfo(packname, PackageManager.GET_SIGNATURES);
            //获取当前应用签名
            return packinfo.signatures[0].toCharsString();

        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();

        }
        return packname;
    }

    /**
     * 获取当前展示 的Activity名称
     *
     * @return
     */
    public String getCurrentActivityName(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        String runningActivity = activityManager.getRunningTasks(1).get(0).topActivity.getClassName();
        return runningActivity;
    }

    /**
     * 获取本应用的SHA1码
     *
     * @param context
     * @return
     */
    public String getCertificateSHA1Fingerprint(Context context) {
        return getCertificateSHA1FingerprintByPackageName(context, context.getPackageName());
    }


    /**
     * 通过应用包名获取应用sha1码
     *
     * @param context
     * @param packageName
     * @return
     */
    public String getCertificateSHA1FingerprintByPackageName(Context context, String packageName) {
        try {
            // 获取包管理器
            PackageManager pm = context.getPackageManager();
            // 获取当前要获取SHA1值的包名，也能够用其它的包名。但须要注意，
            // 返回包含在包中的签名信息
            // 获得包的全部内容信息类
            PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);

            // 签名信息
            Signature[] signatures = packageInfo.signatures;
            if (signatures != null && signatures.length > 0) {
                //将签名转换为字节数组流
                byte[] cert = signatures[0].toByteArray();
                InputStream input = new ByteArrayInputStream(cert);

                // 证书工厂类，这个类实现了出厂合格证算法的功能
                CertificateFactory cf = CertificateFactory.getInstance("X509");

                //X509证书。X.509是一种很通用的证书格式
                X509Certificate c = (X509Certificate) cf.generateCertificate(input);

                // 加密算法的类，这里的參数能够使MD4,MD5等加密算法
                MessageDigest md = MessageDigest.getInstance("SHA1");
                if (c != null) {
                    //获得公钥
                    byte[] publicKey = md.digest(c.getEncoded());
                    //字节到十六进制的格式转换
                    return byte2HexFormatted(publicKey);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 这里是将获取到得编码进行16进制转换
     *
     * @param arr
     * @return
     */
    private String byte2HexFormatted(byte[] arr) {
        StringBuilder str = new StringBuilder(arr.length * 2);
        for (int i = 0; i < arr.length; i++) {
            String h = Integer.toHexString(arr[i]);
            int l = h.length();
            if (l == 1) {
                h = "0" + h;
            }
            if (l > 2) {
                h = h.substring(l - 2, l);
            }
            str.append(h.toUpperCase());
            if (i < (arr.length - 1)) {
                str.append(':');
            }
        }
        return str.toString();
    }

    /**
     * 获取服务上APP版本号
     *
     * @param item
     * @param localVer 本地版本号
     * @return
     */
    public int getVersionOnServer(AppBaseInfo item, int localVer) {
        int version = 0;
        String updType = item.getUpdType();
        int verTypeCode = item.getVerTypeCode();
        try {
            if (TextUtils.isEmpty(updType)
                    || updType.equals("1")
                    || localVer < verTypeCode) {
                // 获取基线版本号
                version = verTypeCode;
            } else {
                // 获取补丁版本号
                version = Integer.parseInt(item.getVerCode());
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        return version;
    }

    /**
     * 获取已安装的插件(APP)信息
     *
     * @param context
     * @param name    插件别名或APP包名
     * @return AppBaseInfo
     */
    public static AppBaseInfo getLocalAppInfo(@NonNull Context context, @NonNull String name) {
        PluginInfo pluginInfo = RePlugin.getPluginInfo(name);
        if (pluginInfo != null) {
            AppBaseInfo baseInfo = new AppBaseInfo();
            baseInfo.setAppName(pluginInfo.getName());
            baseInfo.setAppPackage(pluginInfo.getPackageName());
            baseInfo.setAppAlias(pluginInfo.getAlias());

            baseInfo.setVerSortName(pluginInfo.getVersion() + "");
            baseInfo.setVerTypeCode(pluginInfo.getVersion());
            return baseInfo;
        }
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(name, 0);
            if (pi != null && pi.applicationInfo != null) {
                AppBaseInfo baseInfo = new AppBaseInfo();
                baseInfo.setAppName(pi.applicationInfo.loadLabel(pm).toString());
                baseInfo.setAppPackage(pi.packageName);
                baseInfo.setVerName(pi.versionName);
                baseInfo.setVerCode(pi.versionCode + "");
                baseInfo.setAppIconLocDrawable(pi.applicationInfo.loadIcon(pm));
                return baseInfo;
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 读取本地已安装的APP列表判断已安装的包名com.sgcc.pda开头的APP信息
     *
     * @param context
     * @return
     */
    public static List<AppBaseInfo> getLocalInstalledApp(@NonNull Context context) {
        PackageManager pm = context.getPackageManager();
        List<ApplicationInfo> apps = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
        List<AppBaseInfo> list = new LinkedList<>();
        for (ApplicationInfo item : apps) {
            String pkg = item.packageName;// 包名
            // 过滤三方应用, 保留com.sgcc.pda.开头包名的应用
            if (!pkg.startsWith("com.sgcc.pda")) {
                continue;
            }
            // 通过包名查询应用在市场的信息(应用ID, 分类ID等)
            List<AppBaseInfo> temp = ContentProviderUtil.getAppBaseInfoListBySearchAppName(context, pkg);
            AppBaseInfo app = temp == null || temp.isEmpty() ? new AppBaseInfo() : temp.get(0);

            // APP信息已本地安装的为准
            app.setAppName(item.loadLabel(pm).toString());// app名称
            app.setAppPackage(pkg);// app包名
            try {
                PackageInfo packageInfo = pm.getPackageInfo(pkg, PackageManager.GET_CONFIGURATIONS);
                app.setInstallDataTimeLong(packageInfo.lastUpdateTime);// app更新时间
                app.setVerTypeName(packageInfo.versionName);// app版本名称
                app.setVerTypeCode(packageInfo.versionCode);// app版本号

            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
            list.add(app);
        }
        return list;
    }

    /**
     * 读取本地插件列表判断已安装的插件APP
     *
     * @param context
     * @return
     */
    public static List<AppBaseInfo> getLocalPluginApp(@NonNull Context context) {
        // 插件APP
        List<PluginInfo> plugins = RePlugin.getPluginInfoList();
        List<AppBaseInfo> list = new LinkedList<>();
        for (PluginInfo plugin : plugins) {
            String pkg = plugin.getPackageName();
            // 过滤三方应用, 保留com.sgcc.pda.开头包名的应用
            if (!pkg.startsWith("com.sgcc.pda")) {
                continue;
            }
            // 通过包名查询应用在市场的信息(应用ID, 分类ID等)
            List<AppBaseInfo> temp = ContentProviderUtil.getAppBaseInfoListBySearchAppName(context, pkg);
            AppBaseInfo app = temp == null || temp.isEmpty() ? new AppBaseInfo() : temp.get(0);

            // APP信息已本地文件里的为准
            app.setVerTypeCode(plugin.getVersion());// 版本号
            String path = plugin.getPath();// 插件文件路径
            app.setInstallDataTimeLong(plugin.getApkFile().lastModified());// 使用文件的修改时间当作最后操作时间

            PackageManager pm = context.getPackageManager();
            PackageInfo pkgInfo = pm.getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES);
            if (pkgInfo != null) {
                ApplicationInfo appInfo = pkgInfo.applicationInfo;
                app.setAppName(pm.getApplicationLabel(appInfo).toString());// 得到应用名
                app.setAppPackage(appInfo.packageName);// 得到包名
                app.setVerTypeName(pkgInfo.versionName);// 得到版本信息
            }
            list.add(app);
        }
        return list;
    }

    /**
     * 读取本地WebApp根目录判断已安装的WebApp
     *
     * @param context
     * @return
     */
    public static List<AppBaseInfo> getLocalWebApp(@NonNull Context context) {
        // WebApp root path
        String rootPath = ZipUtil.getWebAppPath();
        File file = new File(rootPath);
        List<AppBaseInfo> list = new LinkedList<>();
        if (file.isDirectory()) {
            File[] files = file.listFiles(new FileFilter() {
                @Override
                public boolean accept(File f) {
                    // 过滤"com.sgcc.pda"开头的文件夹
                    return f.isDirectory() && f.getName().startsWith("com.sgcc.pda");
                }
            });

            for (File item : files) {
                String pkg = item.getName();
                // 通过包名查询应用在市场的信息(应用ID, 分类ID等)
                List<AppBaseInfo> temp = ContentProviderUtil.getAppBaseInfoListBySearchAppName(context, pkg);
                AppBaseInfo app = temp == null || temp.isEmpty() ? new AppBaseInfo() : temp.get(0);

                // WebApp配置文件
                File pkgJson = new File(item, "package.json");
                try {
                    String json = readFile(pkgJson);
                    JSONObject jsonObj = new JSONObject(json);
                    app.setAppName(jsonObj.optString("name"));// APP名称
                    app.setVerTypeName(jsonObj.optString("version"));// 版本名称
                    app.setVerTypeCode(jsonObj.optInt("versionCode"));// 版本号
                    app.setAppPackage(jsonObj.optString("packageName"));// 包名
                    app.setInstallDataTimeLong(pkgJson.lastModified());// APP最后操作时间
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                list.add(app);
            }
        }
        return list;
    }

    /**
     * 读取WebApp配置文件内容
     *
     * @param file
     * @return
     * @throws IOException
     */
    private static String readFile(File file) throws IOException {
        FileInputStream fis = new FileInputStream(file);
        InputStreamReader isr = new InputStreamReader(fis, "utf-8");
        BufferedReader reader = new BufferedReader(isr);
        StringBuilder builder = new StringBuilder();
        String line;
//        while ((line = reader.readLine()) != null) {
//            builder.append(line);
//        }

        do {
            StringBuilder sbInner = new StringBuilder();

            int intC;
            while ((intC = reader.read()) != -1) {
                char innerChar = (char) intC;
                if (sbInner.length() >= Integer.MAX_VALUE) {
                    throw new IOException("input too long");
                }
                sbInner.append(innerChar);
            }
            line = sbInner.toString();

            if (!TextUtils.isEmpty(line))
                builder.append(line);
        } while (!TextUtils.isEmpty(line));

        return builder.toString();
    }

}
